home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / game / think / MUIMineSrc.lha / MUIMineSource / LEWindow.c < prev    next >
C/C++ Source or Header  |  1998-12-16  |  51KB  |  1,539 lines

  1. /*
  2.     MUI custom window class to edit MUIMine difficulty levels
  3. */
  4.  
  5. #include "MUIMine.h"
  6. #include "MFStrings.h"
  7. #include "LevelData.h"
  8. #include "LEWindow.h"
  9.  
  10.  
  11. /*
  12.     structure for holding the level data that is editable
  13. */
  14. struct EditLevelData
  15. {
  16.     char  Name[LEVEL_NAME_SIZE];
  17.     ULONG Level;
  18. };
  19.  
  20.  
  21. /*
  22.     instance data for LEWindow class
  23. */
  24. struct LEWindowData
  25. {
  26.     struct LevelDataList * GivenLevels; // origional level data list
  27.     struct LevelDataList * ReturnLevels;// new level data list after editing
  28.     int NumEditLevels;                  // number of level in edit data list
  29.     struct EditLevelData * EditData;    // edit data list
  30.     struct EditLevelData * SelectedLevel;// selected level or NULL
  31.     struct EditLevelData   UndoData;    // edit level data for undo
  32.     Object * LevelList;                 // level list object
  33.     Object * LevelListview;             // level list view object
  34.     Object * NameString;                // name edit string object
  35.     Object * WidthString;               // width edit string object
  36.     Object * HeightString;              // height edit string object
  37.     Object * MinesString;               // mines edit string object
  38. };
  39.  
  40.  
  41. /********************************************************************
  42.  
  43.     private class methods
  44.  
  45. ********************************************************************/
  46.  
  47. #define MUIM_LEWindow_UndoLevel         (LEWINDOW_TAG_BASE | 0x0801)
  48. #define MUIM_LEWindow_UndoAll           (LEWINDOW_TAG_BASE | 0x0802)
  49. #define MUIM_LEWindow_AddLevel          (LEWINDOW_TAG_BASE | 0x0803)
  50. #define MUIM_LEWindow_DeleteLevel       (LEWINDOW_TAG_BASE | 0x0804)
  51. #define MUIM_LEWindow_ReturnLevels      (LEWINDOW_TAG_BASE | 0x0805)
  52. #define MUIM_LEWindow_SelectLevel       (LEWINDOW_TAG_BASE | 0x0806)
  53. #define MUIM_LEWindow_EditUpdate        (LEWINDOW_TAG_BASE | 0x0807)
  54.  
  55.  
  56. struct EditUpdateParams{ ULONG MethodID; LONG type; };
  57. #define MUIV_LEWindow_EditUpdate_Name   1
  58. #define MUIV_LEWindow_EditUpdate_Width  2
  59. #define MUIV_LEWindow_EditUpdate_Height 3
  60. #define MUIV_LEWindow_EditUpdate_Mines  4
  61.  
  62.  
  63.  
  64. /********************************************************************
  65.  
  66.     prototypes
  67.  
  68. ********************************************************************/
  69.  
  70. struct EditLevelData * CreateEditData(struct LevelDataList * lList);
  71. void SetEditData(struct LEWindowData * data, struct EditLevelData * edData,
  72.                                              int nLevels);
  73. void SetInitialEditData(struct LEWindowData * data);
  74. void FillLevelList(struct LEWindowData * data);
  75.  
  76. struct EditLevelData * GetSelectedLevel(struct LEWindowData * data);
  77. LONG GetLevelIndex(struct LEWindowData * data, struct EditLevelData * edData);
  78. LONG SelectListLevel(struct LEWindowData * data, struct EditLevelData * edData);
  79. void SetEditStrings(struct LEWindowData * data);
  80. int CheckCurrentEditData(Object * obj, struct LEWindowData * data);
  81.  
  82. void SetEditLevel(struct LEWindowData * data, struct EditLevelData * edData);
  83.  
  84.  
  85. /*
  86.     defines for and CheckCurrentEditData() return values
  87. */
  88. #define CHECK_OK                0
  89. #define CHECK_NONAME            1
  90. #define CHECK_NOWIDTH           2
  91. #define CHECK_NOHEIGHT          3
  92. #define CHECK_NOMINES           4
  93. #define CHECK_TOOMANYMINES      5
  94. #define CHECK_DUPLICATE_LEVEL   6
  95. #define CHECK_DUPLICATE_NAME    7
  96.  
  97.  
  98.  
  99. /*
  100.     display function and hook for level list object
  101. */
  102. SAVEDS ASM LONG LevelListDisplayFunc(REG(a2) char **array,
  103.                                      REG(a1) struct EditLevelData *data)
  104. {
  105.     if (data)
  106.     {
  107.         static char width[8], height[8], mines[8];
  108.  
  109.         sprintf(width,  "%d", (int)LVL_WIDTH(data->Level));
  110.         sprintf(height, "%d", (int)LVL_HEIGHT(data->Level));
  111.         sprintf(mines,  "%d", (int)LVL_MINES(data->Level));
  112.         *array++ = data->Name;
  113.         *array++ = width;
  114.         *array++ = height;
  115.         *array   = mines;
  116.     }
  117.     else
  118.     {
  119.         *array++ = GetStr(MSG_LEVELNAMECOL_HEADING);
  120.         *array++ = GetStr(MSG_WIDTHCOL_HEADING);
  121.         *array++ = GetStr(MSG_HEIGHTCOL_HEADING);
  122.         *array   = GetStr(MSG_MINESCOL_HEADING);
  123.     }
  124.  
  125.     return 0;
  126. }
  127.  
  128. static const struct Hook LevelListDisplayHook =
  129. {
  130.     { NULL,NULL }, (void *)LevelListDisplayFunc ,NULL, NULL
  131. };
  132.  
  133.  
  134. /*
  135.     function :    OM_NEW method handler for MFWindow class
  136. */
  137. static ULONG mNew(struct IClass *cl, Object *obj, struct opSet *msg)
  138. {
  139.     struct LevelDataList *givList, *retList;
  140.     STRPTR okbuttlabel, cancelbuttlabel, addbuttlabel, delbuttlabel,
  141.            undothisbuttlabel, undoallbuttlabel, nameeditlabel, widtheditlabel,
  142.            heighteditlabel, mineseditlabel;
  143.     Object *levelList, *levelListview, *nameString, *widthString,
  144.            *heightString, *minesString, *addButt, *delButt, *undotButt,
  145.            *undoaButt, *okButt, *cancelButt;
  146.  
  147.     /*
  148.         get the control characters and labels for the various gadgets
  149.     */
  150.     okbuttlabel = GetStr(MSG_OKBUTT_LABEL);
  151.     cancelbuttlabel = GetStr(MSG_CANCELBUTT_LABEL);
  152.     addbuttlabel = GetStr(MSG_ADDBUTT_LABEL);
  153.     delbuttlabel = GetStr(MSG_DELETEBUTT_LABEL);
  154.     undothisbuttlabel = GetStr(MSG_UNDOTHISBUTT_LABEL);
  155.     undoallbuttlabel = GetStr(MSG_UNDOALLBUTT_LABEL);
  156.     nameeditlabel = GetStr(MSG_NAMEEDIT_LABEL);
  157.     widtheditlabel = GetStr(MSG_WIDTHEDIT_LABEL);
  158.     heighteditlabel = GetStr(MSG_HEIGHTEDIT_LABEL);
  159.     mineseditlabel = GetStr(MSG_MINESEDIT_LABEL);
  160.  
  161.     /*
  162.         get the given level data list initialization attribute,
  163.         fail if not found
  164.     */
  165.     givList = (struct LevelDataList *)GetTagData(MUIA_LEWindow_GivenLevels,
  166.                                                  NULL, msg->ops_AttrList);
  167.     if (givList == NULL)
  168.     {
  169.         return NULL;
  170.     }
  171.  
  172.     /*
  173.         get the return level data list initialization attribute,
  174.         fail if not found
  175.     */
  176.     retList = (struct LevelDataList *)GetTagData(MUIA_LEWindow_ReturnLevels,
  177.                                                  NULL, msg->ops_AttrList);
  178.     if (retList == NULL)
  179.     {
  180.         return NULL;
  181.     }
  182.  
  183.     /*
  184.         create the window object
  185.     */
  186.     obj = (Object *)DoSuperNew(cl, obj,
  187.             MUIA_Window_Title, GetStr(MSG_LEWINDOW_TITLE),
  188.             WindowContents, HGroup,
  189.                 Child, VGroup,
  190.                     MUIA_HorizWeight, 100,
  191.                     Child, levelListview = ListviewObject,
  192.                         MUIA_Listview_DragType, MUIV_Listview_DragType_Immediate,
  193.                         MUIA_CycleChain, TRUE,
  194.                         MUIA_ShortHelp, GetStr(MSG_LEVELLIST_HELP),
  195.                         MUIA_Listview_List, levelList = ListObject,
  196.                             InputListFrame,
  197.                             MUIA_List_Format, "BAR,BAR,BAR,",
  198.                             MUIA_List_Title, TRUE,
  199.                             MUIA_List_DragSortable, TRUE,
  200.                             MUIA_List_AutoVisible, TRUE,
  201.                             MUIA_List_DisplayHook, &LevelListDisplayHook,
  202.                             End,
  203.                         End,
  204.  
  205.                     Child, HGroup,
  206.                         Child, TextObject,
  207.                             StringFrame,
  208.                             MUIA_FramePhantomHoriz, TRUE,
  209.                             MUIA_Text_Contents, nameeditlabel + 2,
  210.                             MUIA_Text_PreParse, "\033r",
  211.                             MUIA_Text_HiChar, (LONG)*nameeditlabel,
  212.                             MUIA_Text_SetMax, TRUE,
  213.                             End,
  214.  
  215.                         Child, nameString = StringObject,
  216.                             StringFrame,
  217.                             MUIA_ControlChar, (LONG)*nameeditlabel,
  218.                             MUIA_String_MaxLen, LEVEL_NAME_SIZE,
  219.                             MUIA_String_AdvanceOnCR, TRUE,
  220.                             MUIA_CycleChain, TRUE,
  221.                             MUIA_ShortHelp, GetStr(MSG_NAMEEDIT_HELP),
  222.                             End,
  223.  
  224.                         End,
  225.  
  226.                     Child, HGroup,
  227.                         MUIA_Group_SameWidth, TRUE,
  228.                         Child, TextObject,
  229.                             StringFrame,
  230.                             MUIA_FramePhantomHoriz, TRUE,
  231.                             MUIA_Text_Contents, widtheditlabel + 2,
  232.                             MUIA_Text_PreParse, "\033r",
  233.                             MUIA_Text_HiChar, (LONG)*widtheditlabel,
  234.                             End,
  235.  
  236.                         Child, widthString = StringObject,
  237.                             StringFrame,
  238.                             MUIA_ControlChar, (LONG)*widtheditlabel,
  239.                             MUIA_String_Accept, "0123456789",
  240.                             MUIA_String_MaxLen, 3,
  241.                             MUIA_String_AdvanceOnCR, TRUE,
  242.                             MUIA_CycleChain, TRUE,
  243.                             MUIA_ShortHelp, GetStr(MSG_WIDTHEDIT_HELP),
  244.                             End,
  245.  
  246.                         Child, TextObject,
  247.                             StringFrame,
  248.                             MUIA_FramePhantomHoriz, TRUE,
  249.                             MUIA_Text_Contents, heighteditlabel + 2,
  250.                             MUIA_Text_PreParse, "\033r",
  251.                             MUIA_Text_HiChar, (LONG)*heighteditlabel,
  252.                             End,
  253.  
  254.                         Child, heightString = StringObject,
  255.                             StringFrame,
  256.                             MUIA_ControlChar, (LONG)*heighteditlabel,
  257.                             MUIA_String_Accept, "0123456789",
  258.                             MUIA_String_MaxLen, 3,
  259.                             MUIA_String_AdvanceOnCR, TRUE,
  260.                             MUIA_CycleChain, TRUE,
  261.                             MUIA_ShortHelp, GetStr(MSG_HEIGHTEDIT_HELP),
  262.                             End,
  263.  
  264.                         Child, TextObject,
  265.                             StringFrame,
  266.                             MUIA_FramePhantomHoriz, TRUE,
  267.                             MUIA_Text_Contents, mineseditlabel + 2,
  268.                             MUIA_Text_PreParse, "\033r",
  269.                             MUIA_Text_HiChar, (LONG)*mineseditlabel,
  270.                             End,
  271.  
  272.                         Child, minesString = StringObject,
  273.                             StringFrame,
  274.                             MUIA_ControlChar, (LONG)*mineseditlabel,
  275.                             MUIA_String_Accept, "0123456789",
  276.                             MUIA_String_MaxLen, 4,
  277.                             MUIA_String_AdvanceOnCR, TRUE,
  278.                             MUIA_CycleChain, TRUE,
  279.                             MUIA_ShortHelp, GetStr(MSG_MINESEDIT_HELP),
  280.                             End,
  281.  
  282.                         End,
  283.  
  284.                     End,
  285.  
  286.                 Child, VGroup,
  287.                     MUIA_HorizWeight, 25,
  288.                     Child, addButt = TextObject,
  289.                         ButtonFrame,
  290.                         MUIA_Background, MUII_ButtonBack,
  291.                         MUIA_InputMode, MUIV_InputMode_RelVerify,
  292.                         MUIA_Text_Contents, addbuttlabel + 2,
  293.                         MUIA_Text_PreParse, "\033c",
  294.                         MUIA_Text_HiChar, (LONG)*addbuttlabel,
  295.                         MUIA_ControlChar, (LONG)*addbuttlabel,
  296.                         MUIA_ShortHelp, GetStr(MSG_ADDBUTT_HELP),
  297.                         End,
  298.  
  299.                     Child, delButt = TextObject,
  300.                         ButtonFrame,
  301.                         MUIA_Background, MUII_ButtonBack,
  302.                         MUIA_InputMode, MUIV_InputMode_RelVerify,
  303.                         MUIA_Text_Contents, delbuttlabel + 2,
  304.                         MUIA_Text_PreParse, "\033c",
  305.                         MUIA_Text_HiChar, (LONG)*delbuttlabel,
  306.                         MUIA_ControlChar, (LONG)*delbuttlabel,
  307.                         MUIA_ShortHelp, GetStr(MSG_DELETEBUTT_HELP),
  308.                         End,
  309.  
  310.                     Child, VSpace(0),
  311.  
  312.                     Child, undotButt = TextObject,
  313.                         ButtonFrame,
  314.                         MUIA_Background, MUII_ButtonBack,
  315.                         MUIA_InputMode, MUIV_InputMode_RelVerify,
  316.                         MUIA_Text_Contents, undothisbuttlabel + 2,
  317.                         MUIA_Text_PreParse, "\033c",
  318.                         MUIA_Text_HiChar, (LONG)*undothisbuttlabel,
  319.                         MUIA_ControlChar, (LONG)*undothisbuttlabel,
  320.                         MUIA_ShortHelp, GetStr(MSG_UNDOTHISBUTT_HELP),
  321.                         End,
  322.  
  323.                     Child, undoaButt = TextObject,
  324.                         ButtonFrame,
  325.                         MUIA_Background, MUII_ButtonBack,
  326.                         MUIA_InputMode, MUIV_InputMode_RelVerify,
  327.                         MUIA_Text_Contents, undoallbuttlabel + 2,
  328.                         MUIA_Text_PreParse, "\033c",
  329.                         MUIA_Text_HiChar, (LONG)*undoallbuttlabel,
  330.                         MUIA_ControlChar, (LONG)*undoallbuttlabel,
  331.                         MUIA_ShortHelp, GetStr(MSG_UNDOALLBUTT_HELP),
  332.                         End,
  333.  
  334.                     Child, VSpace(0),
  335.  
  336.                     Child, okButt = TextObject,
  337.                         ButtonFrame,
  338.                         MUIA_Background, MUII_ButtonBack,
  339.                         MUIA_InputMode, MUIV_InputMode_RelVerify,
  340.                         MUIA_Text_Contents, okbuttlabel + 2,
  341.                         MUIA_Text_PreParse, "\033c",
  342.                         MUIA_Text_HiChar, (LONG)*okbuttlabel,
  343.                         MUIA_ControlChar, (LONG)*okbuttlabel,
  344.                         MUIA_CycleChain, TRUE,
  345.                         MUIA_ShortHelp, GetStr(MSG_LE_OKBUTT_HELP),
  346.                         End,
  347.  
  348.                     Child, cancelButt = TextObject,
  349.                         ButtonFrame,
  350.                         MUIA_Background, MUII_ButtonBack,
  351.                         MUIA_InputMode, MUIV_InputMode_RelVerify,
  352.                         MUIA_Text_Contents, cancelbuttlabel + 2,
  353.                         MUIA_Text_PreParse, "\033c",
  354.                         MUIA_Text_HiChar, (LONG)*cancelbuttlabel,
  355.                         MUIA_ControlChar, (LONG)*cancelbuttlabel,
  356.                         MUIA_ShortHelp, GetStr(MSG_LE_CANCELBUTT_HELP),
  357.                         MUIA_CycleChain, TRUE,
  358.                         End,
  359.  
  360.                     End,
  361.  
  362.                 End,
  363.             MUIA_Window_DefaultObject, okButt,
  364.             TAG_MORE, msg->ops_AttrList);
  365.  
  366.  
  367.     if (obj)
  368.     {
  369.         /*
  370.             the window object was successfully created
  371.         */
  372.         struct LEWindowData * data = INST_DATA(cl, obj);
  373.  
  374.         /*
  375.             initialize the window's instance data
  376.         */
  377.         data->GivenLevels = givList;        // given level data list
  378.         data->ReturnLevels = retList;       // return level data list
  379.         data->NumEditLevels = 0;            // number of level in edit data list
  380.         data->EditData = NULL;              // edit data list
  381.         data->SelectedLevel = NULL;         // selected level
  382.         data->LevelList = levelList;        // level list object
  383.         data->LevelListview = levelListview;// level list view object
  384.         data->NameString = nameString;      // name edit string object
  385.         data->WidthString = widthString;    // width edit string object
  386.         data->HeightString = heightString;  // height edit string object
  387.         data->MinesString = minesString;    // mines edit string object
  388.  
  389.         /*
  390.             initialize the return level data list to empty
  391.         */
  392.         retList->NumLevels = 0;
  393.         retList->LevelList = NULL;
  394.  
  395.         /*
  396.             setup the initial edit data and fill the level list
  397.         */
  398.         SetInitialEditData(data);
  399.  
  400.         /*
  401.             set up notifications
  402.         */
  403.         DoMethod(cancelButt, MUIM_Notify, MUIA_Pressed, FALSE,
  404.                     obj, 3, MUIM_Set, MUIA_Window_CloseRequest, TRUE);
  405.  
  406.         DoMethod(okButt, MUIM_Notify, MUIA_Pressed, FALSE,
  407.                     obj, 1, MUIM_LEWindow_ReturnLevels);
  408.  
  409.         DoMethod(undotButt, MUIM_Notify, MUIA_Pressed, FALSE,
  410.                     obj, 1, MUIM_LEWindow_UndoLevel);
  411.  
  412.         DoMethod(undoaButt, MUIM_Notify, MUIA_Pressed, FALSE,
  413.                     obj, 1, MUIM_LEWindow_UndoAll);
  414.  
  415.         DoMethod(addButt, MUIM_Notify, MUIA_Pressed, FALSE,
  416.                     obj, 1, MUIM_LEWindow_AddLevel);
  417.  
  418.         DoMethod(delButt, MUIM_Notify, MUIA_Pressed, FALSE,
  419.                     obj, 1, MUIM_LEWindow_DeleteLevel);
  420.  
  421.         DoMethod(levelList, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime,
  422.                     obj, 1, MUIM_LEWindow_SelectLevel);
  423.  
  424.         DoMethod(nameString, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
  425.                     obj, 2, MUIM_LEWindow_EditUpdate, MUIV_LEWindow_EditUpdate_Name);
  426.  
  427.         DoMethod(widthString, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
  428.                     obj, 2, MUIM_LEWindow_EditUpdate, MUIV_LEWindow_EditUpdate_Width);
  429.  
  430.         DoMethod(heightString, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
  431.                     obj, 2, MUIM_LEWindow_EditUpdate, MUIV_LEWindow_EditUpdate_Height);
  432.  
  433.         DoMethod(minesString, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
  434.                     obj, 2, MUIM_LEWindow_EditUpdate, MUIV_LEWindow_EditUpdate_Mines);
  435.     }
  436.  
  437.     /*
  438.         return the object (or NULL)
  439.     */
  440.     return (ULONG)obj;
  441. }
  442.  
  443.  
  444. /*
  445.     function :    OM_DELETE method handler for LEWindow class
  446. */
  447. static ULONG mDispose(struct IClass *cl, Object *obj, Msg msg)
  448. {
  449.     struct LEWindowData *data = INST_DATA(cl, obj);
  450.  
  451.     if (data->EditData)
  452.     {
  453.         FreeVec((APTR)data->EditData);
  454.     }
  455.  
  456.     return DoSuperMethodA(cl, obj, msg);
  457. }
  458.  
  459.  
  460. /*
  461.     function :    OM_SET method handler for LEWindow class
  462. */
  463. /*
  464. static ULONG mSet(struct IClass *cl, Object *obj, struct opSet * msg)
  465. {
  466.     struct LEWindowData *data = INST_DATA(cl,obj);
  467.     struct TagItem *tags, *tag;
  468.  
  469.     for (tags = msg->ops_AttrList; tag = NextTagItem(&tags); )
  470.     {
  471.         switch (tag->ti_Tag)
  472.         {
  473.         }
  474.     }
  475.  
  476.     return DoSuperMethodA(cl, obj, (APTR)msg);
  477. }
  478. */
  479. /*
  480.     function :    OM_GET method handler for LEWindow class
  481. */
  482. /*
  483. static ULONG mGet(struct IClass *cl, Object *obj, struct opGet * msg)
  484. {
  485.     struct LEWindowData *data = INST_DATA(cl, obj);
  486.     ULONG *store = msg->opg_Storage;
  487.  
  488.     if (msg->opg_AttrID == MUIA_LEWindow_Level)
  489.     {
  490.         *store = (ULONG)data->DisplayedLevel;
  491.         return TRUE;
  492.     }
  493.  
  494.     return DoSuperMethodA(cl, obj, (APTR)msg);
  495. }
  496. */
  497.  
  498.  
  499. /*
  500.     function :  MUIM_LEWindow_UndoLevel method handler for LEWindow class
  501.  
  502.                 This Method reinitializes the edit strings with the level
  503.                 data from the currently selected level (if any) undoing
  504.                 any changes that have been made since the level was last
  505.                 selected.
  506. */
  507. static ULONG mUndoLevel(struct IClass *cl, Object *obj, Msg msg)
  508. {
  509.     struct LEWindowData *data = INST_DATA(cl, obj);
  510.     if (data->SelectedLevel)
  511.     {
  512.         LONG idx;
  513.         *data->SelectedLevel = data->UndoData;
  514.         SetEditStrings(data);
  515.  
  516.         idx = GetLevelIndex(data, data->SelectedLevel);;
  517.         if (idx >= 0)
  518.         {
  519.             DoMethod(data->LevelList, MUIM_List_Redraw, idx);
  520.         }
  521.     }
  522.     SetAttrs(obj, MUIA_Window_ActiveObject, data->NameString, TAG_DONE);
  523.  
  524.     return 0;
  525. }
  526.  
  527. /*
  528.     function :  MUIM_LEWindow_UndoAll method handler for LEWindow class
  529.  
  530.                 This method deletes any existing edit data, reinitializes
  531.                 the edit data from the given level data list and rebuilds
  532.                 the level list.
  533. */
  534. static ULONG mUndoAll(struct IClass *cl, Object *obj, Msg msg)
  535. {
  536.     struct LEWindowData *data = INST_DATA(cl, obj);
  537.  
  538.     DoMethod(data->LevelList, MUIM_KillNotify, MUIA_List_Active);
  539.  
  540.     SetInitialEditData(data);
  541.  
  542.     DoMethod(data->LevelList, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime,
  543.                         obj, 1, MUIM_LEWindow_SelectLevel);
  544.  
  545.     SetAttrs(obj, MUIA_Window_ActiveObject, data->LevelListview, TAG_DONE);
  546.     return 0;
  547. }
  548.  
  549. /*
  550.     function :  MUIM_LEWindow_AddLevel method handler for LEWindow class
  551.  
  552.                 This method reallocates the edit data to add one extra level
  553.                 at the end initialized to defaults. The level list is rebuilt
  554.                 and the new level is selected for editing.
  555. */
  556. static ULONG mAddLevel(struct IClass *cl, Object *obj, Msg msg)
  557. {
  558.     struct LEWindowData *data = INST_DATA(cl, obj);
  559.  
  560.     /*
  561.         check for valid current edit level
  562.     */
  563.     if (CheckCurrentEditData(obj, data) == CHECK_OK)
  564.     {
  565.         /*
  566.             attempt to allocate a new edit data buffer for one level
  567.             more than the current number of levels in the level list
  568.         */
  569.         LONG n = 0;
  570.         struct EditLevelData * newEdData;
  571.  
  572.         DoMethod(data->LevelList, OM_GET, MUIA_List_Entries, &n);
  573.         n++;
  574.         newEdData = (struct EditLevelData *)AllocVec(
  575.                                     n * sizeof(struct EditLevelData),
  576.                                     MEMF_CLEAR);
  577.         if (newEdData)
  578.         {
  579.             /*
  580.                 read the level list and copy the existing edit level data
  581.                 to the new edit data
  582.             */
  583.             LONG i;
  584.             struct EditLevelData *p1, *p2;
  585.  
  586.             for (i = 0, p1 = newEdData; i < n - 1; i++, p1++)
  587.             {
  588.                 p2 = NULL;
  589.                 DoMethod(data->LevelList, MUIM_List_GetEntry, i, &p2);
  590.                 if (p2)
  591.                 {
  592.                     *p1 = *p2;
  593.                 }
  594.             }
  595.  
  596.             /*
  597.                 delete the old edit data and set the new
  598.             */
  599.             FreeVec((APTR)data->EditData);
  600.             data->EditData = newEdData;
  601.             data->NumEditLevels = n;
  602.  
  603.             /*
  604.                 fill the level list with the new edit level data,
  605.                 select the last entry in the list and make it the
  606.                 current edit level
  607.             */
  608.             DoMethod(data->LevelList, MUIM_KillNotify, MUIA_List_Active);
  609.             FillLevelList(data);
  610.             DoMethod(data->LevelList, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime,
  611.                         obj, 1, MUIM_LEWindow_SelectLevel);
  612.             p1 = &newEdData[n - 1];
  613.             SelectListLevel(data, p1);
  614.             SetEditLevel(data, p1);
  615.             SetAttrs(obj, MUIA_Window_ActiveObject, data->NameString,
  616.                           TAG_DONE);
  617.         }
  618.     }
  619.  
  620.     return 0;
  621. }
  622.  
  623. /*
  624.     function :  MUIM_LEWindow_DeleteLevel method handler for LEWindow class
  625.  
  626.                 This metod checks if there is a level selected in the level
  627.                 list and if there is asks the user if they really want to
  628.                 delete the level. If the user confirms that they want to
  629.                 delete the level then the edit data is reallocated without
  630.                 the selected level and the level list is rebuilt.
  631. */
  632. static ULONG mDeleteLevel(struct IClass *cl, Object *obj, Msg msg)
  633. {
  634.     struct LEWindowData *data = INST_DATA(cl, obj);
  635.     struct EditLevelData * selLevel = GetSelectedLevel(data);
  636.  
  637.     /*
  638.         make sure we have a selected level
  639.     */
  640.     if (selLevel)
  641.     {
  642.         /*
  643.             get the number of entries in the list and make sure it is
  644.             greater than zero (it should be since we have a selected
  645.             entry)
  646.         */
  647.         LONG n = 0;
  648.         DoMethod(data->LevelList, OM_GET, MUIA_List_Entries, &n);
  649.         if (n > 0)
  650.         {
  651.             LONG i;
  652.             /*
  653.                 query the user if they really want to delete the level
  654.             */
  655.             if (*selLevel->Name == 0)
  656.             {
  657.                 i = MUI_RequestA(_app(obj), obj, 0,
  658.                                  GetStr(MSG_LEWINDOW_TITLE),
  659.                                  GetStr(MSG_YESNO_GADGETS),
  660.                                  GetStr(MSG_QUERY_DELETEUNNAMED),
  661.                                  NULL);
  662.             }
  663.             else
  664.             {
  665.                 ULONG nameptr = (ULONG)selLevel->Name;
  666.                 i = MUI_RequestA(_app(obj), obj, 0,
  667.                                  GetStr(MSG_LEWINDOW_TITLE),
  668.                                  GetStr(MSG_YESNO_GADGETS),
  669.                                  GetStr(MSG_QUERY_DELETELEVEL_FMT),
  670.                                  &nameptr);
  671.             }
  672.             if (i)
  673.             {
  674.                 /*
  675.                     attempt to allocate a new edit data buffer with one level
  676.                     less than the current number of levels in the level list
  677.                 */
  678.                 struct EditLevelData * newEdData;
  679.                 n--;
  680.                 newEdData = (struct EditLevelData *)AllocVec(
  681.                                             n * sizeof(struct EditLevelData),
  682.                                             MEMF_CLEAR);
  683.                 if (newEdData)
  684.                 {
  685.                     /*
  686.                         read the level list and copy the existing edit level
  687.                         data to the new edit data making sure we skip the
  688.                         selected level
  689.                     */
  690.                     struct EditLevelData *p1, *p2;
  691.  
  692.                     p1 = newEdData;
  693.                     for (i = 0; i <= n; i++)
  694.                     {
  695.                         p2 = NULL;
  696.                         DoMethod(data->LevelList, MUIM_List_GetEntry, i, &p2);
  697.                         if (p2  &&  p2 != selLevel)
  698.                         {
  699.                             *p1++ = *p2;
  700.                         }
  701.                     }
  702.  
  703.                     /*
  704.                         delete the old edit data and set the new
  705.                     */
  706.                     FreeVec((APTR)data->EditData);
  707.                     data->EditData = newEdData;
  708.                     data->NumEditLevels = n;
  709.  
  710.                     /*
  711.                         fill the level list with the new edit level data
  712.                         and deselect any selected data
  713.                     */
  714.                     DoMethod(data->LevelList, MUIM_KillNotify, MUIA_List_Active);
  715.                     FillLevelList(data);
  716.                     DoMethod(data->LevelList, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime,
  717.                                 obj, 1, MUIM_LEWindow_SelectLevel);
  718.                     SetEditLevel(data, NULL);
  719.                     SetAttrs(obj, MUIA_Window_ActiveObject, data->LevelListview,
  720.                                   TAG_DONE);
  721.                 }
  722.             }
  723.         }
  724.     }
  725.  
  726.     return 0;
  727. }
  728.  
  729. /*
  730.     function :  MUIM_LEWindow_ReturnLevels method handler for LEWindow class
  731.  
  732.                 This method first checks if there is a current edit level
  733.                 and if there is it attempts to valid the current edit data.
  734.                 If the current edit data is validated ok then the current
  735.                 edit level is updated with the edit data otherwise an error
  736.                 message is given and the current level is not updated.
  737.  
  738.                 Once the current edit level (if any) is updated the return
  739.                 level data list is built from the edit data and the given
  740.                 level data list. The MUIA_Window_CloseRequest attribute of
  741.                 the window is then set to TRUE to signal the close of the
  742.                 window.
  743. */
  744. static ULONG mReturnLevels(struct IClass *cl, Object *obj, Msg msg)
  745. {
  746.     struct LEWindowData *data = INST_DATA(cl, obj);
  747.  
  748.     /*
  749.         check for valid current edit data
  750.     */
  751.     if (CheckCurrentEditData(obj, data) == CHECK_OK)
  752.     {
  753.         /*
  754.             get the number of entries in the level list
  755.         */
  756.         LONG n = 0;
  757.         DoMethod(data->LevelList, OM_GET, MUIA_List_Entries, &n);
  758.         if (n)
  759.         {
  760.             /*
  761.                 attempt to initialize the return level data list
  762.             */
  763.             if (InitLevelDataList(data->ReturnLevels, data->NumEditLevels))
  764.             {
  765.                 LONG i;
  766.                 struct EditLevelData * pEd;
  767.                 struct LevelData *pLv1, *pLv = data->ReturnLevels->LevelList;
  768.  
  769.                 /*
  770.                     copy the edit data to the new level list
  771.                 */
  772.                 for (i = 0; i < data->NumEditLevels; i++)
  773.                 {
  774.                     /*
  775.                         get this list entry's data
  776.                     */
  777.                     pEd = NULL;
  778.                     DoMethod(data->LevelList, MUIM_List_GetEntry, i, &pEd);
  779.                     if (pEd)
  780.                     {
  781.                         strcpy(pLv->Name, pEd->Name);
  782.                         pLv->Level = pEd->Level;
  783.                     }
  784.                     pLv++;
  785.                 }
  786.  
  787.                 /*
  788.                     for each level in the origional level data list look
  789.                     for the same level in the new level data list and
  790.                     when found copy the origional best time dat to the
  791.                     new list
  792.                 */
  793.                 pLv = data->GivenLevels->LevelList;
  794.                 for (i = data->GivenLevels->NumLevels; i > 0; i--)
  795.                 {
  796.                     pLv1 = FindLevel(data->ReturnLevels, pLv->Level);
  797.                     if (pLv1)
  798.                     {
  799.                         int j;
  800.                         struct BestTime *p1, *p2;
  801.  
  802.                         p1 = pLv1->BestTimes;
  803.                         p2 = pLv->BestTimes;
  804.                         for (j = 3; j > 0; j--)
  805.                         {
  806.                             *p1++ = *p2++;
  807.                         }
  808.                     }
  809.                     pLv++;
  810.                 }
  811.             }
  812.         }
  813.  
  814.         /*
  815.             set the window's close request so that the window will be closed
  816.         */
  817.         SetAttrs(obj, MUIA_Window_CloseRequest, TRUE, TAG_DONE);
  818.     }
  819.  
  820.     return 0;
  821. }
  822.  
  823. /*
  824.     function :  MUIM_LEWindow_SelectLevel method handler for LEWindow class
  825.  
  826.                 This method first checks if the level selected in the level
  827.                 list differs from the current edit level, if they are the
  828.                 same then no action is taken.
  829.  
  830.                 Next attempts to update the current edit data, if the current
  831.                 edit data cannot be saved then a warning message is given and
  832.                 the problem data reselected for correction.
  833.  
  834.                 Once the current level (if any) is updated the level that is
  835.                 now selected in the list becomes the currnt edit level and
  836.                 the level edit strings are set with the new level's data.
  837. */
  838. static ULONG mSelectLevel(struct IClass *cl, Object *obj, Msg msg)
  839. {
  840.     struct LEWindowData *data = INST_DATA(cl, obj);
  841.     struct EditLevelData * selLevel = GetSelectedLevel(data);
  842.  
  843.     /*
  844.         check that the selected level is different from the current
  845.         edit level
  846.     */
  847.     if (selLevel != data->SelectedLevel)
  848.     {
  849.         /*
  850.             check for valid current edit data
  851.         */
  852.         if (CheckCurrentEditData(obj, data) == CHECK_OK)
  853.         {
  854.             /*
  855.                 make the selected level the current edit level, set up the
  856.                 edit strings for the level
  857.             */
  858.             SetEditLevel(data, selLevel);
  859.         }
  860.     }
  861.  
  862.     return 0;
  863. }
  864.  
  865. /*
  866.     function :  handler for MUIM_LEWindow_EditUpdate
  867. */
  868. static ULONG mEditUpdate(struct IClass * cl, Object * obj, struct EditUpdateParams * msg)
  869. {
  870.     struct LEWindowData *data = INST_DATA(cl, obj);
  871.  
  872.     if (data->SelectedLevel)
  873.     {
  874.         BOOL update = FALSE;
  875.  
  876.         switch (msg->type)
  877.         {
  878.             case MUIV_LEWindow_EditUpdate_Name:
  879.             {
  880.                 STRPTR p = NULL;
  881.                 DoMethod(data->NameString, OM_GET, MUIA_String_Contents, &p);
  882.                 if (p)
  883.                 {
  884.                     strcpy(data->SelectedLevel->Name, p);
  885.                     update = TRUE;
  886.                 }
  887.                 break;
  888.             }
  889.  
  890.             case MUIV_LEWindow_EditUpdate_Width:
  891.             {
  892.                 LONG w = -1;
  893.                 DoMethod(data->WidthString, OM_GET, MUIA_String_Integer, &w);
  894.                 if (w >= 0)
  895.                 {
  896.                     data->SelectedLevel->Level = LVL_SET_WIDTH(data->SelectedLevel->Level, w);
  897.                     update = TRUE;
  898.                 }
  899.                 break;
  900.             }
  901.  
  902.             case MUIV_LEWindow_EditUpdate_Height:
  903.             {
  904.                 LONG h = -1;
  905.                 DoMethod(data->HeightString, OM_GET, MUIA_String_Integer, &h);
  906.                 if (h >= 0)
  907.                 {
  908.                     data->SelectedLevel->Level = LVL_SET_HEIGHT(data->SelectedLevel->Level, h);
  909.                     update = TRUE;
  910.                 }
  911.                 break;
  912.             }
  913.  
  914.             case MUIV_LEWindow_EditUpdate_Mines:
  915.             {
  916.                 LONG m =-1;
  917.                 DoMethod(data->MinesString, OM_GET, MUIA_String_Integer, &m);
  918.                 if (m >= 0)
  919.                 {
  920.                     data->SelectedLevel->Level = LVL_SET_MINES(data->SelectedLevel->Level, m);
  921.                     update = TRUE;
  922.                 }
  923.                 break;
  924.             }
  925.         }
  926.  
  927.         /*
  928.             check if updated edit data and if so then update the
  929.             selected level list entry
  930.         */
  931.         if (update)
  932.         {
  933.             LONG idx = GetLevelIndex(data, data->SelectedLevel);
  934.             if (idx >= 0  &&  idx < data->NumEditLevels)
  935.             {
  936.                 DoMethod(data->LevelList, MUIM_List_Redraw, idx);
  937.             }
  938.         }
  939.     }
  940.  
  941.     return 0;
  942. }
  943.  
  944. /*
  945.     function :    class dispatcher
  946. */
  947. SAVEDS ASM ULONG LEWindowDispatcher(
  948.         REG(a0) struct IClass *cl,
  949.         REG(a2) Object *obj,
  950.         REG(a1) Msg msg)
  951. {
  952.     switch (msg->MethodID)
  953.     {
  954.         case OM_NEW:     return mNew    (cl, obj, (APTR)msg);
  955.         case OM_DISPOSE: return mDispose(cl, obj, (APTR)msg);
  956. //        case OM_SET:     return mSet    (cl, obj, (APTR)msg);
  957. //        case OM_GET:     return mGet    (cl, obj, (APTR)msg);
  958.  
  959.         case MUIM_LEWindow_UndoLevel:
  960.             return mUndoLevel(cl, obj, (APTR)msg);
  961.  
  962.         case MUIM_LEWindow_UndoAll:
  963.             return mUndoAll(cl, obj, (APTR)msg);
  964.  
  965.         case MUIM_LEWindow_AddLevel:
  966.             return mAddLevel(cl, obj, (APTR)msg);
  967.  
  968.         case MUIM_LEWindow_DeleteLevel:
  969.             return mDeleteLevel(cl, obj, (APTR)msg);
  970.  
  971.         case MUIM_LEWindow_ReturnLevels:
  972.             return mReturnLevels(cl, obj, (APTR)msg);
  973.  
  974.         case MUIM_LEWindow_SelectLevel:
  975.             return mSelectLevel(cl, obj, (APTR)msg);
  976.  
  977.         case MUIM_LEWindow_EditUpdate:
  978.             return mEditUpdate(cl, obj, (APTR)msg);
  979.     }
  980.  
  981.     return DoSuperMethodA(cl, obj, msg);
  982. }
  983.  
  984.  
  985. /*
  986.     function :    allocates and initialize an EditLevelData array for the
  987.                   level data in the given level data list
  988.  
  989.     parameters :  lList = pointer to the LevelDataList to create the edit
  990.                           data for
  991.  
  992.     return :      pointer to the EditLevelData array if allocated and
  993.                   initialized ok, NULL otherwise
  994. */
  995. struct EditLevelData * CreateEditData(struct LevelDataList * lList)
  996. {
  997.     struct EditLevelData * eld = NULL;
  998.  
  999.     /*
  1000.         make sure there is level data
  1001.     */
  1002.     if (lList  &&  lList->NumLevels  &&  lList->LevelList)
  1003.     {
  1004.         /*
  1005.             attempt to allocate the edit level data
  1006.         */
  1007.         eld = (struct EditLevelData *)AllocVec(lList->NumLevels *
  1008.                                                 sizeof(struct EditLevelData),
  1009.                                                 0);
  1010.         if (eld)
  1011.         {
  1012.             /*
  1013.                 initialize the edit level data from the level data list
  1014.             */
  1015.             int i;
  1016.             struct EditLevelData * eld1;
  1017.             struct LevelData * pLevel;
  1018.             for (i = lList->NumLevels, eld1 = eld, pLevel = lList->LevelList;
  1019.                  i > 0;
  1020.                  i--, eld1++, pLevel++)
  1021.             {
  1022.                 strcpy(eld1->Name, pLevel->Name);
  1023.                 eld1->Level = pLevel->Level;
  1024.             }
  1025.         }
  1026.     }
  1027.  
  1028.     /*
  1029.         return the edit level data or NULL if it was not created
  1030.     */
  1031.     return eld;
  1032. }
  1033.  
  1034. /*
  1035.     function :    sets the edit data for the window, first checks if there
  1036.                   is existing edit data and frees it if it exists, sets the
  1037.                   given edit data, clears the level list and rebuilds the
  1038.                   level list from the new edit data
  1039.  
  1040.     parameters :  data = pointer to the LEWindowData to set the edit data for
  1041.                   edData = the new edit data to set for the window
  1042.                   nLevels = number of levels in the edit level data array
  1043.  
  1044.     return :      none
  1045. */
  1046. void SetEditData(struct LEWindowData * data, struct EditLevelData * edData,
  1047.                                              int nLevels)
  1048. {
  1049.     /*
  1050.         check if there is existing edit level data and delete it if it does
  1051.     */
  1052.     if (data->EditData)
  1053.     {
  1054.         FreeVec((APTR)data->EditData);
  1055.     }
  1056.     /*
  1057.         assign the new edit level data
  1058.     */
  1059.     data->NumEditLevels = nLevels;
  1060.     data->EditData = edData;
  1061. }
  1062.  
  1063. /*
  1064.     function :    sets up the edit data for the window from the given level
  1065.                   data list deleting any existing edit data and rebuilds the
  1066.                   level list from the newly initialized edit data
  1067.  
  1068.     parameters :  data = pointer to the LEWindowData to initialize the edit
  1069.                          data for
  1070.  
  1071.     return :      none
  1072. */
  1073. void SetInitialEditData(struct LEWindowData * data)
  1074. {
  1075.     /*
  1076.         attempt to create the edit data for the given level data list
  1077.     */
  1078.     struct EditLevelData * eld = CreateEditData(data->GivenLevels);
  1079.     if (eld)
  1080.     {
  1081.         /*
  1082.             set the new edit data to the window and rebuild the level list
  1083.         */
  1084.         SetEditData(data, eld, data->GivenLevels->NumLevels);
  1085.         FillLevelList(data);
  1086.     }
  1087.     /*
  1088.         initialize current level to none and initialize edit strings
  1089.     */
  1090.     SetEditLevel(data, NULL);
  1091. }
  1092.  
  1093. /*
  1094.     function :    clears the level list then fills it from the window's
  1095.                   edit data
  1096.  
  1097.     parameters :  data = pointer to the LEWindowData of the window to fill
  1098.                          the level list of
  1099.  
  1100.     return :      none
  1101. */
  1102. void FillLevelList(struct LEWindowData * data)
  1103. {
  1104.     int i;
  1105.     struct EditLevelData * eld;
  1106.  
  1107.     /*
  1108.         set the MUIA_List_Quiet attribute of the level list while it
  1109.         is being updated
  1110.     */
  1111.     SetAttrs(data->LevelList, MUIA_List_Quiet, TRUE, TAG_DONE);
  1112.  
  1113.     /*
  1114.         clear the level list
  1115.     */
  1116.     DoMethod(data->LevelList, MUIM_List_Clear);
  1117.  
  1118.     /*
  1119.         add each level from the edit level data to the list
  1120.     */
  1121.     for (i = data->NumEditLevels, eld = data->EditData;
  1122.          i > 0;
  1123.          i--, eld++)
  1124.     {
  1125.         DoMethod(data->LevelList, MUIM_List_InsertSingle,
  1126.                                   (APTR)eld, MUIV_List_Insert_Bottom);
  1127.     }
  1128.  
  1129.     /*
  1130.         clear the MUIA_List_Quiet attribute of the level list now that
  1131.         updating is completed
  1132.     */
  1133.     SetAttrs(data->LevelList, MUIA_List_Quiet, FALSE, TAG_DONE);
  1134. }
  1135.  
  1136.  
  1137. /*
  1138.     function :    checks if there is a selected entry in the level list
  1139.                   and if there is get the edit level data for the entry
  1140.  
  1141.     parameters :  data = pointer to the LEWindowData
  1142.  
  1143.     return :      pointer to the selected level's edit data or NULL
  1144. */
  1145. struct EditLevelData * GetSelectedLevel(struct LEWindowData * data)
  1146. {
  1147.     struct EditLevelData * eld = NULL;
  1148.  
  1149.     /*
  1150.         get the active entry in the list
  1151.     */
  1152.     DoMethod(data->LevelList, MUIM_List_GetEntry,
  1153.                               MUIV_List_GetEntry_Active, &eld);
  1154.  
  1155.     return eld;
  1156. }
  1157.  
  1158. /*
  1159.     function :    Gets the level list index of the given edit level
  1160.  
  1161.     parameters :  data = pointer to the LEWindowData
  1162.                   edData = pointer to the edit data to find index from
  1163.  
  1164.     return :      the list index or -1 if not in list
  1165. */
  1166. LONG GetLevelIndex(struct LEWindowData * data, struct EditLevelData * edData)
  1167. {
  1168.     LONG idx = -1;
  1169.     LONG i, n = 0;
  1170.     struct EditLevelData * eld;
  1171.  
  1172.     /*
  1173.         get number of entries in the list
  1174.     */
  1175.     DoMethod(data->LevelList, OM_GET, MUIA_List_Entries, &n);
  1176.  
  1177.     /*
  1178.         step through the list looking for the given entry
  1179.     */
  1180.     for (i = 0; i < n; i++)
  1181.     {
  1182.         eld = NULL;
  1183.         DoMethod(data->LevelList, MUIM_List_GetEntry, i, &eld);
  1184.         if (eld  &&  eld == edData)
  1185.         {
  1186.             /*
  1187.                 found the entry, set the return index and exit the loop
  1188.             */
  1189.             idx = i;
  1190.             break;
  1191.         }
  1192.     }
  1193.  
  1194.     return idx;
  1195. }
  1196.  
  1197. /*
  1198.     function :    Selects the given edit level in the level list
  1199.  
  1200.     parameters :  data = pointer to the LEWindowData
  1201.                   edData = pointer to the edit data to select in level list
  1202.  
  1203.     return :      the list index of the selected level or -1 if not in list
  1204. */
  1205. LONG SelectListLevel(struct LEWindowData * data, struct EditLevelData * edData)
  1206. {
  1207.     /*
  1208.         find the level in the level list
  1209.     */
  1210.     LONG idx = GetLevelIndex(data, edData);
  1211.     if (idx < 0)
  1212.     {
  1213.         idx = MUIV_List_Active_Off;
  1214.     }
  1215.     /*
  1216.         the level was found in the level list, select it
  1217.     */
  1218.     SetAttrs(data->LevelList, MUIA_NoNotify, TRUE,
  1219.                               MUIA_List_Active, idx,
  1220.                               TAG_DONE);
  1221.  
  1222.     return idx;
  1223. }
  1224.  
  1225. /*
  1226.     function :    sets the contents of the edit strings from the selected
  1227.                   level's edit data
  1228.  
  1229.     parameters :  data = pointer to the LEWindowData for this window
  1230.  
  1231.     return :      none
  1232. */
  1233. void SetEditStrings(struct LEWindowData * data)
  1234. {
  1235.     struct EditLevelData * eld = data->SelectedLevel;
  1236.     /*
  1237.         check if there is a current level
  1238.     */
  1239.     if (eld)
  1240.     {
  1241.         /*
  1242.             set name edit string with the level's name and enable the string
  1243.         */
  1244.         SetAttrs(data->NameString, MUIA_NoNotify, TRUE,
  1245.                                    MUIA_String_Contents, eld->Name,
  1246.                                    MUIA_Disabled, FALSE,
  1247.                                    TAG_DONE);
  1248.  
  1249.         /*
  1250.             set the width edit string with the level's width and enable
  1251.             the string
  1252.         */
  1253.         SetAttrs(data->WidthString, MUIA_NoNotify, TRUE,
  1254.                                     MUIA_String_Integer, LVL_WIDTH(eld->Level),
  1255.                                     MUIA_Disabled, FALSE,
  1256.                                     TAG_DONE);
  1257.  
  1258.         /*
  1259.             set the height edit string with the level's height and enable
  1260.             the string
  1261.         */
  1262.         SetAttrs(data->HeightString, MUIA_NoNotify, TRUE,
  1263.                                      MUIA_String_Integer, LVL_HEIGHT(eld->Level),
  1264.                                      MUIA_Disabled, FALSE,
  1265.                                      TAG_DONE);
  1266.  
  1267.         /*
  1268.             set the mines edit string with the level's height and enable
  1269.             the string
  1270.         */
  1271.         SetAttrs(data->MinesString, MUIA_NoNotify, TRUE,
  1272.                                     MUIA_String_Integer, LVL_MINES(eld->Level),
  1273.                                     MUIA_Disabled, FALSE,
  1274.                                     TAG_DONE);
  1275.     }
  1276.     else
  1277.     {
  1278.         /*
  1279.             no selected level, disable the edut strings
  1280.         */
  1281.         SetAttrs(data->NameString,   MUIA_NoNotify, TRUE,
  1282.                                      MUIA_String_Contents, "",
  1283.                                      MUIA_Disabled, TRUE, TAG_DONE);
  1284.         SetAttrs(data->WidthString,  MUIA_NoNotify, TRUE,
  1285.                                      MUIA_String_Contents, "",
  1286.                                      MUIA_Disabled, TRUE, TAG_DONE);
  1287.         SetAttrs(data->HeightString, MUIA_NoNotify, TRUE,
  1288.                                      MUIA_String_Contents, "",
  1289.                                      MUIA_Disabled, TRUE, TAG_DONE);
  1290.         SetAttrs(data->MinesString,  MUIA_NoNotify, TRUE,
  1291.                                      MUIA_String_Contents, "",
  1292.                                      MUIA_Disabled, TRUE, TAG_DONE);
  1293.     }
  1294. }
  1295.  
  1296. /*
  1297.     function :    checks if there is selected edit data, if there is then
  1298.                   checks for valid edit string data, if string data valid
  1299.                   then checks for duplicate level and if there is none then
  1300.                   updates the selected edit data with the edit string values
  1301.  
  1302.     parameter :   obj = pointer to the LEWindow object
  1303.                   data = pointer to the LEWindowData
  1304.  
  1305.     return :      CHECK_xxx code (see defines above)
  1306. */
  1307. int CheckCurrentEditData(Object * obj, struct LEWindowData * data)
  1308. {
  1309.     int ret = CHECK_OK;
  1310.     struct EditLevelData * edData = data->SelectedLevel;
  1311.     /*
  1312.         check if we have a selected level, return CHECK_OK if not
  1313.     */
  1314.     if (edData)
  1315.     {
  1316.         Object * errObj = NULL;
  1317.         STRPTR dupname = NULL;
  1318.         LONG width, height, mines;
  1319.  
  1320.         /*
  1321.             check that the name is not the empty string
  1322.         */
  1323.         if (edData->Name[0] == 0)
  1324.         {
  1325.             errObj = data->NameString;
  1326.             ret = CHECK_NONAME;
  1327.         }
  1328.         /*
  1329.             check that the width is set
  1330.         */
  1331.         else if ((width = LVL_WIDTH(edData->Level)) == 0)
  1332.         {
  1333.             errObj = data->WidthString;
  1334.             ret = CHECK_NOWIDTH;
  1335.         }
  1336.         /*
  1337.             check that the height is set
  1338.         */
  1339.         else if ((height = LVL_HEIGHT(edData->Level)) == 0)
  1340.         {
  1341.             errObj = data->HeightString;
  1342.             ret = CHECK_NOHEIGHT;
  1343.         }
  1344.         /*
  1345.             check that the number of mines is set
  1346.         */
  1347.         else if ((mines = LVL_MINES(edData->Level)) == 0)
  1348.         {
  1349.             errObj = data->MinesString;
  1350.             ret = CHECK_NOMINES;
  1351.         }
  1352.         /*
  1353.             check if there are less mines than cells
  1354.         */
  1355.         else if (mines >= (height * width))
  1356.         {
  1357.             errObj = data->MinesString;
  1358.             ret = CHECK_TOOMANYMINES;
  1359.         }
  1360.         /*
  1361.             check for duplicate level or name
  1362.         */
  1363.         else
  1364.         {
  1365.             int i;
  1366.             struct EditLevelData * eld = data->EditData;
  1367.             ULONG level = MAKE_LEVEL(width, height, mines);
  1368.  
  1369.             for (i = data->NumEditLevels; i > 0; i--, eld++)
  1370.             {
  1371.                 /*
  1372.                     check each level except the selected level for a
  1373.                     matching level, set the error state and exit the
  1374.                     loop if a match is found, other wise check for a
  1375.                     duplicate name and set the error state and exit
  1376.                     the loop if a duplicate is found
  1377.                 */
  1378.                 if (eld != edData)
  1379.                 {
  1380.                     if (eld->Level == level)
  1381.                     {
  1382.                         errObj = data->WidthString;
  1383.                         dupname = eld->Name;
  1384.                         ret = CHECK_DUPLICATE_LEVEL;
  1385.                         break;
  1386.                     }
  1387.  
  1388.                     if (strcmp(eld->Name, edData->Name) == 0)
  1389.                     {
  1390.                         errObj = data->NameString;
  1391.                         dupname = eld->Name;
  1392.                         ret = CHECK_DUPLICATE_NAME;
  1393.                         break;
  1394.                     }
  1395.                 }
  1396.             }
  1397.         }
  1398.  
  1399.         /*
  1400.             if we have an error then display the appropriate error
  1401.             message, make sure that this level is still selected
  1402.             and set the input focus to the error object
  1403.         */
  1404.         if (ret != CHECK_OK)
  1405.         {
  1406.             Object * app = _app(obj);
  1407.             char errStr[256];
  1408.             LONG copyStrId = 0;
  1409.  
  1410.             /*
  1411.                 select the error string for the problem
  1412.             */
  1413.             switch (ret)
  1414.             {
  1415.                 case CHECK_NONAME:
  1416.                     copyStrId = MSG_NOLEVELNAME_ERR;
  1417.                     break;
  1418.  
  1419.                 case CHECK_NOWIDTH:
  1420.                 case CHECK_NOHEIGHT:
  1421.                 case CHECK_NOMINES:
  1422.                     copyStrId = MSG_UNSETLEVELDATA_ERR;
  1423.                     break;
  1424.  
  1425.                 case CHECK_TOOMANYMINES:
  1426.                     copyStrId = MSG_TOOMANYMINES_ERR;
  1427.                     break;
  1428.  
  1429.                 case CHECK_DUPLICATE_LEVEL:
  1430.                     sprintf(errStr, GetStr(MSG_DUPLEVEL_ERR_FMT), dupname);
  1431.                     break;
  1432.  
  1433.                 case CHECK_DUPLICATE_NAME:
  1434.                     sprintf(errStr, GetStr(MSG_DUPNAME_ERR_FMT), dupname);
  1435.                     break;
  1436.  
  1437.                 default:
  1438.                     copyStrId = MSG_UNKNOWNLEVELDATA_ERR;
  1439.                     break;
  1440.             }
  1441.  
  1442.             /*
  1443.                 if the error message is a simple error without formatting
  1444.                 then copy it to the error message buffer
  1445.             */
  1446.             if (copyStrId)
  1447.             {
  1448.                 strcpy(errStr, GetStr(copyStrId));
  1449.             }
  1450.  
  1451.             /*
  1452.                 inform the user of the error
  1453.             */
  1454.             MUI_RequestA(app, obj, 0, GetStr(MSG_LEWINDOW_TITLE),
  1455.                                       GetStr(MSG_CONTINUE_GADGET),
  1456.                                       errStr, NULL);
  1457.  
  1458.             /*
  1459.                 make sure the Selected level is still selected in the
  1460.                 level list
  1461.             */
  1462.             SelectListLevel(data, edData);
  1463.             SetEditLevel(data, edData);
  1464.  
  1465.             /*
  1466.                 select the error string object so that corrections
  1467.                 may be easily made
  1468.             */
  1469.             SetAttrs(obj, MUIA_Window_ActiveObject, errObj, TAG_DONE);
  1470.         }
  1471.     }
  1472.  
  1473.     return ret;
  1474. }
  1475.  
  1476.  
  1477. /*
  1478.     function :    selects the given level for editing,
  1479.  
  1480.     parameters :  data = pointer to the LEWindowData
  1481.                   newLevel = pointer to the level edit data
  1482. */
  1483. void SetEditLevel(struct LEWindowData * data, struct EditLevelData * newLevel)
  1484. {
  1485.     /*
  1486.         check if level is given, if so select it for editing
  1487.         otherwise clears any current selection
  1488.     */
  1489.     if (newLevel)
  1490.     {
  1491.         /*
  1492.             copy undo data
  1493.         */
  1494.         data->UndoData = *newLevel;
  1495.     }
  1496.     else
  1497.     {
  1498.         /*
  1499.             clear undo data
  1500.         */
  1501.         data->UndoData.Level = 0;
  1502.         data->UndoData.Name[0] = 0;
  1503.     }
  1504.  
  1505.     /*
  1506.         set the new selected level
  1507.     */
  1508.     data->SelectedLevel = newLevel;
  1509.  
  1510.     /*
  1511.         set edit strings
  1512.     */
  1513.     SetEditStrings(data);
  1514. }
  1515.  
  1516.  
  1517. /*
  1518.     function :    creates the LEWindow MUI custom class
  1519.  
  1520.     return :      pointer to the created custom class or NULL
  1521. */
  1522. struct MUI_CustomClass * CreateLEWindowClass()
  1523. {
  1524.     return MUI_CreateCustomClass(NULL, MUIC_Window, NULL,
  1525.                                        sizeof(struct LEWindowData),
  1526.                                        LEWindowDispatcher);
  1527. }
  1528.  
  1529. /*
  1530.     function :    deletes of the LEWindow custom class
  1531.  
  1532.     parameters :  mcc = pointer to the LEWindow MUI_CustomClass to delete
  1533. */
  1534. void DeleteLEWindowClass(struct MUI_CustomClass * mcc)
  1535. {
  1536.     MUI_DeleteCustomClass(mcc);
  1537. }
  1538.  
  1539.